import bcrypt from 'bcryptjs'
import { DataTypes } from 'sequelize'
import { sequelize } from '../config/database.js'

const Admin = sequelize.define('Admin', {
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true,
  },
  username: {
    type: DataTypes.STRING(50),
    allowNull: false,
    comment: '管理员用户名',
  },
  password: {
    type: DataTypes.STRING(255),
    allowNull: false,
    comment: '密码哈希',
  },
  email: {
    type: DataTypes.STRING(100),
    allowNull: false,
    validate: {
      isEmail: true,
    },
    comment: '邮箱',
  },
  phone: {
    type: DataTypes.STRING(20),
    allowNull: true,
    comment: '手机号',
  },
  real_name: {
    type: DataTypes.STRING(50),
    allowNull: true,
    comment: '真实姓名',
  },
  nickname: {
    type: DataTypes.STRING(100),
    allowNull: true,
    comment: '昵称',
  },
  role: {
    type: DataTypes.ENUM('super_admin', 'admin'),
    allowNull: false,
    defaultValue: 'admin',
    comment: '角色：super_admin-超级管理员，admin-普通管理员',
  },
  is_active: {
    type: DataTypes.BOOLEAN,
    defaultValue: true,
    comment: '是否激活',
  },
  last_login_at: {
    type: DataTypes.DATE,
    allowNull: true,
    comment: '最后登录时间',
  },
  last_login_ip: {
    type: DataTypes.STRING(45),
    allowNull: true,
    comment: '最后登录IP',
  },
  created_at: {
    type: DataTypes.DATE,
    defaultValue: DataTypes.NOW,
  },
  updated_at: {
    type: DataTypes.DATE,
    defaultValue: DataTypes.NOW,
  },
}, {
  tableName: 'admins',
  timestamps: true,
  createdAt: 'created_at',
  updatedAt: 'updated_at',
  indexes: [
    {
      name: 'idx_admins_username',
      unique: true,
      fields: ['username'],
    },
    {
      name: 'idx_admins_email',
      unique: true,
      fields: ['email'],
    },
    {
      name: 'idx_admins_phone',
      unique: true,
      fields: ['phone'],
    },
    {
      name: 'idx_admins_role',
      fields: ['role'],
    },
    {
      name: 'idx_admins_is_active',
      fields: ['is_active'],
    },
  ],
  hooks: {
    beforeCreate: async (admin) => {
      if (admin.password) {
        admin.password = await bcrypt.hash(admin.password, 12)
      }
    },
    beforeUpdate: async (admin) => {
      if (admin.changed('password') && admin.password) {
        admin.password = await bcrypt.hash(admin.password, 12)
      }
    },
  },
})

// 实例方法
Admin.prototype.toJSON = function () {
  const values = { ...this.get() }
  delete values.password // 不返回密码

  // 映射字段名以匹配前端期望
  if (values.real_name !== undefined) {
    values.name = values.real_name
  }

  return values
}

Admin.prototype.validatePassword = async function (password) {
  return await bcrypt.compare(password, this.password)
}

Admin.prototype.updateLoginInfo = async function (ip) {
  this.last_login_at = new Date()
  this.last_login_ip = ip
  await this.save()
}

Admin.prototype.isSuperAdmin = function () {
  return this.role === 'super_admin'
}

Admin.prototype.resetPassword = async function (newPassword) {
  this.password = await bcrypt.hash(newPassword, 12)
  await this.save()
  return this
}

// 类方法
Admin.findByUsername = function (username) {
  return this.findOne({ where: { username } })
}

Admin.createAdmin = async function (adminData) {
  return await this.create(adminData)
}

Admin.getList = function (options = {}) {
  const { page = 1, limit = 20, role, isActive } = options
  const where = {}

  if (role) {
    where.role = role
  }

  if (typeof isActive === 'boolean') {
    where.is_active = isActive
  }

  return this.findAndCountAll({
    where,
    attributes: { exclude: ['password'] },
    order: [['created_at', 'DESC']],
    limit,
    offset: (page - 1) * limit,
  })
}

// 创建默认超级管理员
Admin.createDefaultSuperAdmin = async function () {
  const existingSuperAdmin = await this.findOne({
    where: { role: 'super_admin' },
  })

  if (!existingSuperAdmin) {
    await this.create({
      username: 'admin',
      password: 'admin123',
      real_name: '超级管理员',
      role: 'super_admin',
    })
    console.log('✅ Default super admin created: username=admin, password=admin123')
  }
}

export default Admin
